package com.java.simple.smallspring.jdbc.core;

import com.java.simple.smallspring.jdbc.IncorrectResultSetColumnCountException;
import com.java.simple.smallspring.jdbc.support.JdbcUtils;
import com.java.simple.smallspring.util.NumberUtils;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.Objects;

/**
 * @author zhoujunlin
 * @date 2022年11月19日 20:30
 * @desc
 */
public class SingleColumnRowMapper<T> implements RowMapper<T> {

    private Class<?> requireType;

    public SingleColumnRowMapper() {
    }

    public SingleColumnRowMapper(Class<?> requireType) {
        this.requireType = requireType;
    }

    @Override
    public T mapRow(ResultSet rs, int rowNum) throws SQLException {
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();
        if (columnCount != 1) {
            throw new IncorrectResultSetColumnCountException(1, rowNum);
        }
        Object result = getColumnValue(rs, 1, this.requireType);
        if (Objects.nonNull(result) && Objects.nonNull(this.requireType) && !this.requireType.isInstance(result)) {
            // 已经提取出来的数据跟需要的类型不匹配 这里需要转换一下
            try {
                return (T) convertValueToRequireType(result, this.requireType);
            } catch (IllegalArgumentException ex) {

            }
        }
        return (T) result;
    }

    protected Object getColumnValue(ResultSet rs, int index, Class<?> requireType) throws SQLException {
        if (Objects.nonNull(requireType)) {
            return JdbcUtils.getResultSetValue(rs, index, requireType);
        }
        return getColumnValue(rs, index);
    }

    protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
        return JdbcUtils.getResultSetValue(rs, index);
    }

    private Object convertValueToRequireType(Object value, Class<?> requireType) {
        if (String.class == requireType) {
            return value.toString();
        } else if (Number.class.isAssignableFrom(requireType)) {
            if (value instanceof Number) {
                return NumberUtils.convertNumberToTargetClass((Number) value, (Class<Number>) requireType);
            } else {
                return NumberUtils.parseNumber(value.toString(), (Class<Number>) requireType);
            }
        }
        // 这里暂时不添加spring-core里的类型转换处理
        /*else if (this.conversionService != null && this.conversionService.canConvert(value.getClass(), requiredType)) {
            return this.conversionService.convert(value, requiredType);
        }*/
        else {
            throw new IllegalArgumentException("Value[" + value + "] is of type[" + value.getClass().getName() + "]" +
                    "and cannot be converted to require type[" + requireType.getName() + "]");
        }
    }

}
